package controller

import (
	"encoding/json"
	"net/http"
	"strconv"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common/i18n"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/websocket"
	"github.com/gin-gonic/gin"
)

type NotificationController struct {
	service *service.NotificationService
}

func NewNotificationController() *NotificationController {
	return &NotificationController{service: service.NewNotificationService()}
}

// Create 创建通知
func (c *NotificationController) Create(ctx *gin.Context) {
	var req struct {
		UserID  int64  `json:"user_id" binding:"required"`
		TypeID  int64  `json:"type_id" binding:"required"`
		Title   string `json:"title" binding:"required"`
		Content string `json:"content" binding:"required"`
		Data    string `json:"data"`
		Status  string `json:"status" binding:"required,oneof=UNREAD READ"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	notification := &models.Notification{
		UserID:  req.UserID,
		TypeID:  req.TypeID,
		Title:   req.Title,
		Content: req.Content,
		Data:    models.JSON([]byte(req.Data)),
		Status:  req.Status,
	}

	if err := c.service.CreateNotification(ctx, notification); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "创建失败", err)
		return
	}

	// 创建成功后推送 WebSocket 消息
	go func(n *models.Notification) {
		msg := map[string]interface{}{
			"type": "notification",
			"data": n,
		}
		if msgBytes, err := json.Marshal(msg); err == nil {
			websocket.GlobalHub.BroadcastToUser(n.UserID, msgBytes)
		}
	}(notification)

	common.Success(ctx, gin.H{"msg": "创建成功"})
}

// List 分页获取通知
func (c *NotificationController) List(ctx *gin.Context) {
	userID, _ := strconv.ParseInt(ctx.Query("user_id"), 10, 64)
	page, _ := strconv.Atoi(ctx.DefaultQuery("pageIndex", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "20"))
	// 查询已读未读
	readStatus := ctx.DefaultQuery("readStatus", "UNREAD")

	list, total, err := c.service.ListNotifications(ctx, userID, page, pageSize, readStatus)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "查询失败", err)
		return
	}
	common.Success(ctx, gin.H{"data": list, "total": total})
}

// MarkAsRead 标记为已读
func (c *NotificationController) MarkAsRead(ctx *gin.Context) {
	userID, _ := strconv.ParseInt(ctx.Query("user_id"), 10, 64)
	notificationID, _ := strconv.ParseInt(ctx.Query("notification_id"), 10, 64)

	if err := c.service.MarkAsRead(ctx, userID, notificationID); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "操作失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "已读"})
}

// Delete 批量删除通知
func (c *NotificationController) Delete(ctx *gin.Context) {
	var req struct {
		UserID          int64   `json:"user_id" binding:"required"`
		NotificationIDs []int64 `json:"notification_ids" binding:"required"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}
	if err := c.service.BatchDeleteNotification(ctx, req.UserID, req.NotificationIDs); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "删除失败", err)
		return
	}
	common.Success(ctx, gin.H{"msg": "删除成功"})
}

// ListNotificationTypes 获取所有通知类型
func (c *NotificationController) ListNotificationTypes(ctx *gin.Context) {
	types, err := c.service.ListNotificationTypes(ctx)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, i18n.MsgNotificationTypeQueryFailed, err)
		return
	}
	common.Success(ctx, gin.H{"data": types})
}

// GetNotificationType 获取单个通知类型
func (c *NotificationController) GetNotificationType(ctx *gin.Context) {
	id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_id", err)
		return
	}

	notificationType, err := c.service.GetNotificationTypeByID(ctx, id)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, i18n.MsgNotificationTypeQueryFailed, err)
		return
	}
	common.Success(ctx, gin.H{"data": notificationType})
}

// CreateNotificationType 创建通知类型
func (c *NotificationController) CreateNotificationType(ctx *gin.Context) {
	var notificationType models.NotificationType
	if err := ctx.ShouldBindJSON(&notificationType); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	if err := c.service.CreateNotificationType(ctx, &notificationType); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "create_failed", err)
		return
	}

	common.Success(ctx, gin.H{"data": notificationType})
}

// UpdateNotificationType 更新通知类型
func (c *NotificationController) UpdateNotificationType(ctx *gin.Context) {
	id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_id", err)
		return
	}

	var notificationType models.NotificationType
	if err := ctx.ShouldBindJSON(&notificationType); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	notificationType.ID = uint(id)
	if err := c.service.UpdateNotificationType(ctx, &notificationType); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "update_failed", err)
		return
	}

	common.Success(ctx, gin.H{"data": notificationType})
}

// DeleteNotificationType 删除通知类型
func (c *NotificationController) DeleteNotificationType(ctx *gin.Context) {
	id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_id", err)
		return
	}

	if err := c.service.DeleteNotificationType(ctx, id); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "delete_failed", err)
		return
	}

	common.Success(ctx, gin.H{"message": "删除成功"})
}

// PublishNotification 发布通知
// @Summary 发布通知
// @Description 发布卡片通知或系统通知
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishNotificationRequest true "发布通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish [post]
func (c *NotificationController) PublishNotification(ctx *gin.Context) {
	var req PublishNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 验证通知类型
	if req.TypeID != 2 && req.TypeID != 3 {
		common.Error(ctx, http.StatusBadRequest, "不支持的通知类型", nil)
		return
	}

	// 发布通知
	var err error
	if req.TypeID == 2 {
		// 卡片通知
		err = c.service.PublishCardNotification(ctx, req.UserID, req.Title, req.Content, req.Data)
	} else {
		// 系统通知
		err = c.service.PublishSystemNotification(ctx, req.UserID, req.Title, req.Content, req.Data)
	}

	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "发布通知失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "通知发布成功"})
}

// PublishBatchNotification 批量发布通知
// @Summary 批量发布通知
// @Description 批量发布通知给多个用户
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishBatchNotificationRequest true "批量发布通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish-batch [post]
func (c *NotificationController) PublishBatchNotification(ctx *gin.Context) {
	var req PublishBatchNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 验证用户ID列表
	if len(req.UserIDs) == 0 {
		common.Error(ctx, http.StatusBadRequest, "用户ID列表不能为空", nil)
		return
	}

	// 验证通知类型
	if req.TypeID != 2 && req.TypeID != 3 {
		common.Error(ctx, http.StatusBadRequest, "不支持的通知类型", nil)
		return
	}

	// 批量发布通知
	err := c.service.PublishBatchNotification(ctx, req.UserIDs, req.TypeID, req.Title, req.Content, req.Data)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "批量发布通知失败", err)
		return
	}

	common.Success(ctx, gin.H{
		"msg":        "批量通知发布成功",
		"user_count": len(req.UserIDs),
	})
}

// PublishCardStatusNotification 发布卡片状态变更通知
// @Summary 发布卡片状态变更通知
// @Description 发布卡片状态变更通知
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishCardStatusNotificationRequest true "卡片状态变更通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish-card-status [post]
func (c *NotificationController) PublishCardStatusNotification(ctx *gin.Context) {
	var req PublishCardStatusNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 发布卡片状态变更通知
	err := c.service.PublishCardStatusNotification(ctx, req.UserID, req.CardID, req.OldStatus, req.NewStatus, req.AdditionalData)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "发布卡片状态变更通知失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "卡片状态变更通知发布成功"})
}

// PublishCardTransactionNotification 发布卡片交易通知
// @Summary 发布卡片交易通知
// @Description 发布卡片交易通知
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishCardTransactionNotificationRequest true "卡片交易通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish-card-transaction [post]
func (c *NotificationController) PublishCardTransactionNotification(ctx *gin.Context) {
	var req PublishCardTransactionNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 发布卡片交易通知
	err := c.service.PublishCardTransactionNotification(ctx, req.UserID, req.CardID, req.TransactionType, req.Amount, req.Currency, req.AdditionalData)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "发布卡片交易通知失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "卡片交易通知发布成功"})
}

// PublishSystemAlertNotification 发布系统警告通知
// @Summary 发布系统警告通知
// @Description 发布系统警告通知
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishSystemAlertNotificationRequest true "系统警告通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish-system-alert [post]
func (c *NotificationController) PublishSystemAlertNotification(ctx *gin.Context) {
	var req PublishSystemAlertNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 发布系统警告通知
	err := c.service.PublishSystemAlertNotification(ctx, req.UserID, req.AlertType, req.Message, req.AdditionalData)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "发布系统警告通知失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "系统警告通知发布成功"})
}

// PublishBalanceChangeNotification 发布余额变更通知
// @Summary 发布余额变更通知
// @Description 发布余额变更通知
// @Tags notifications
// @Accept json
// @Produce json
// @Param request body PublishBalanceChangeNotificationRequest true "余额变更通知请求"
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 400 {object} map[string]interface{} "请求错误"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/publish-balance-change [post]
func (c *NotificationController) PublishBalanceChangeNotification(ctx *gin.Context) {
	var req PublishBalanceChangeNotificationRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "参数错误", err)
		return
	}

	// 发布余额变更通知
	err := c.service.PublishBalanceChangeNotification(ctx, req.UserID, req.ChangeType, req.Amount, req.Currency, req.NewBalance, req.AdditionalData)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "发布余额变更通知失败", err)
		return
	}

	common.Success(ctx, gin.H{"msg": "余额变更通知发布成功"})
}

// GetNotificationTypes 获取通知类型列表
// @Summary 获取通知类型列表
// @Description 获取所有可用的通知类型
// @Tags notifications
// @Produce json
// @Success 200 {object} map[string]interface{} "成功响应"
// @Failure 500 {object} map[string]interface{} "服务器错误"
// @Router /api/notifications/types [get]
func (c *NotificationController) GetNotificationTypes(ctx *gin.Context) {
	notificationTypes, err := c.service.GetAllNotificationTypes(ctx)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "获取通知类型失败", err)
		return
	}

	common.Success(ctx, gin.H{"data": notificationTypes})
}

// 请求结构体定义
type PublishNotificationRequest struct {
	UserID  int64                  `json:"user_id" binding:"required"`
	TypeID  int64                  `json:"type_id" binding:"required"`
	Title   string                 `json:"title" binding:"required"`
	Content string                 `json:"content" binding:"required"`
	Data    map[string]interface{} `json:"data"`
}

type PublishBatchNotificationRequest struct {
	UserIDs []int64                `json:"user_ids" binding:"required"`
	TypeID  int64                  `json:"type_id" binding:"required"`
	Title   string                 `json:"title" binding:"required"`
	Content string                 `json:"content" binding:"required"`
	Data    map[string]interface{} `json:"data"`
}

type PublishCardStatusNotificationRequest struct {
	UserID         int64                  `json:"user_id" binding:"required"`
	CardID         string                 `json:"card_id" binding:"required"`
	OldStatus      string                 `json:"old_status" binding:"required"`
	NewStatus      string                 `json:"new_status" binding:"required"`
	AdditionalData map[string]interface{} `json:"additional_data"`
}

type PublishCardTransactionNotificationRequest struct {
	UserID          int64                  `json:"user_id" binding:"required"`
	CardID          string                 `json:"card_id" binding:"required"`
	TransactionType string                 `json:"transaction_type" binding:"required"`
	Amount          string                 `json:"amount" binding:"required"`
	Currency        string                 `json:"currency" binding:"required"`
	AdditionalData  map[string]interface{} `json:"additional_data"`
}

type PublishSystemAlertNotificationRequest struct {
	UserID         int64                  `json:"user_id" binding:"required"`
	AlertType      string                 `json:"alert_type" binding:"required"`
	Message        string                 `json:"message" binding:"required"`
	AdditionalData map[string]interface{} `json:"additional_data"`
}

type PublishBalanceChangeNotificationRequest struct {
	UserID         int64                  `json:"user_id" binding:"required"`
	ChangeType     string                 `json:"change_type" binding:"required"`
	Amount         string                 `json:"amount" binding:"required"`
	Currency       string                 `json:"currency" binding:"required"`
	NewBalance     string                 `json:"new_balance" binding:"required"`
	AdditionalData map[string]interface{} `json:"additional_data"`
}
